package cn.zz.veggie.persistence.repository;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.springframework.stereotype.Repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.zz.comm.core.types.query.PageQuery;
import cn.zz.comm.exception.classes.FatalErrorException;
import cn.zz.comm.util.CollectorUtil;
import cn.zz.comm.util.DateTimeUtil;
import cn.zz.veggie.model.domain.Order;
import cn.zz.veggie.model.query.OrderQuery;
import cn.zz.veggie.persistence.dao.OrderMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 订单表(Order)repo
 *
 * @author zhongq
 * @since 2024-05-25 15:14:56
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class OrderRepository {

	private final OrderMapper orderMapper;

	public Order findById(Integer id) {
		Objects.requireNonNull(id);
		return orderMapper.selectById(id);
	}

	public Map<Integer, Order> findByIds(Collection<Integer> ids) {
		if (CollectionUtil.isEmpty(ids)) {
			return Collections.emptyMap();
		}
		final List<Order> records = orderMapper.selectBatchIds(ids);
		return CollectorUtil.btmByKeyFun(records, Order::getId);
	}

	public Order findOne(OrderQuery query) {
		final LambdaQueryWrapper<Order> queryWrapper = query.toQueryWrapper();
		final Page<Order> page = query.toPage(PageQuery.first().setSearchCount(false));
		return CollUtil.getFirst(orderMapper.selectList(page, queryWrapper));
	}

	public List<Order> findByPage(OrderQuery query, PageQuery page) {
		final LambdaQueryWrapper<Order> queryWrapper = query.toQueryWrapper();
		final Page<Order> adminPage = query.toPage(page);
		final List<Order> admins = orderMapper.selectList(adminPage, queryWrapper);
		page.setTotal(((int) adminPage.getTotal()));
		return admins;
	}

	public List<Order> findWithPage(OrderQuery query, PageQuery page) {
		final LambdaQueryWrapper<Order> queryWrapper = query.toQueryWrapper();
		final Page<Order> adminPage = query.toPage(page);
		return orderMapper.selectList(adminPage, queryWrapper);
	}

	public void save(Order order) {
		Objects.requireNonNull(order);
		if (order.getId() == null) {
			// insert
			final int effect = orderMapper.insert(order);
			if (effect != 1) {
				throw new FatalErrorException("created order fail ");
			}
			log.info("created order for {}", order.getId());
		} else {
			// update
			final int effect = orderMapper.updateById(order);
			if (effect != 1) {
				throw new FatalErrorException("update order fail ");
			}
			log.info("updated order for {}", order.getId());
		}
	}

	public void deleteById(Integer id) {
		Objects.requireNonNull(id);
		final int effect = orderMapper.deleteById(id);
		if (effect != 1) {
			log.error("delete");
			throw new FatalErrorException("delete order fail ");
		}
		log.info("delete order for {}", id);
	}

	public void deleteByIds(Collection<Integer> ids) {
		if (CollUtil.isEmpty(ids)) {
			return;
		}
		final int effect = orderMapper.deleteByIds(ids);
		log.info("delete order for {}", effect);
	}

	public void updateStatus(List<Integer> ids, Integer status) {
		final long currentTime = DateTimeUtil.unixTime();
		ids.forEach(id -> {
			Order order = new Order();
			order.setId(id);
			order.setStatus(status);
			order.setUpdatedAt(currentTime);
			orderMapper.updateById(order);
		});
	}
}